(파이썬) 02 Functions and Getting Help

Reference

  • Kaggle 홈페이지 - Kaggle
  • 3강 ‘Functions and Getting Help’ - Python Micro-Course Home Page

개요(Intro)

앞서 printabs 와 같은 함수를 사용해 보았습니다. 파이썬에는 이 외에도 수 많은 내장 함수들을 가지고 있고 자신만의 함수를 정의하여 사용할 수도 있습니다.

이번 강에서는 함수를 정의하고 사용하는 방법에 대해 배워보겠습니다.




도움말 활용(Getting Help)

만약 abs 함수의 기능이 무엇인지 잊어버렸다면 어떻게 하시겠습니까?

help()함수는 아마 파이썬 함수 중에서도 가장 중요한 함수일 것입니다. help()함수의 정확한 사용법을 알게 된다면 대부분의 다른 함수들을 이해하는 열쇠를 쥐고 있는 것과 다름 없습니다.

예제,

help(round)

출력,

Help on built-in function round in module builtins:

round(...)
round(number[, ndigits]) -> number

Round a number to a given precision in decimal digits (default 0 digits).
This returns an int when called with one argument, otherwise the
same type as the number. ndigits may be negative.

`help()`함수는 2 가지를 보여줍니다:1. 해당 함수의 헤더 `round(number[, ndigits])`. 이 경우 `round()` 함수가 `number`로 설정한 인자를 취한다는 것을 알 수 있습니다. 또한 사용자는 선택적으로 `ndigits`로 설정된 별도의 인자를 제공 할 수 있습니다.2. 해당 함수의 기능에 대한 (영어)설명

Common pitfall(흔히하는 실수)

함수(function)를 찾을 때 함수의 이름을 전달해야하며 함수를 호출 한 결과는 전달하지 말아야합니다.

What happens if we invoke help on a call to the function abs()?

결과를 확인해 보세요->

help(round(-2.01))

원하던 결과가 아님

Help on int object:

class int(object)
| int(x=0) -> integer
| int(x, base=10) -> integer
|
| Convert a number or string to an integer, or return 0 if no arguments
| are given. If x is a number, return x.__int__(). For floating point
| numbers, this truncates towards zero.
|
| If x is not a number or if base is given, then x must be a string,
| bytes, or bytearray instance representing an integer literal in the
| given base. The literal can be preceded by '+' or '-' and be surrounded
| by whitespace. The base defaults to 10. Valid bases are 0 and 2-36.
| Base 0 means to interpret the base from the string as an integer literal.
| >>> int('0b100', base=0)
| 4
|
| Methods defined here:
|
| __abs__(self, /)
| abs(self)
|
| __add__(self, value, /)
| Return self+value.
|
| __and__(self, value, /)
| Return self&value.
|
| __bool__(self, /)
| self != 0
|
| __ceil__(...)
| Ceiling of an Integral returns itself.
|
| __divmod__(self, value, /)
| Return divmod(self, value).
|
| __eq__(self, value, /)
| Return self==value.
|
| __float__(self, /)
| float(self)
|
| __floor__(...)
| Flooring an Integral returns itself.
|
| __floordiv__(self, value, /)
| Return self//value.
|
| __format__(...)
| default object formatter
|
| __ge__(self, value, /)
| Return self>=value.
|
| __getattribute__(self, name, /)
| Return getattr(self, name).
|
| __getnewargs__(...)
|
| __gt__(self, value, /)
| Return self>value.
|
| __hash__(self, /)
| Return hash(self).
|
| __index__(self, /)
| Return self converted to an integer, if self is suitable for use as an index into a list.
|
| __int__(self, /)
| int(self)
|
| __invert__(self, /)
| ~self
|
| __le__(self, value, /)
| Return self<=value.
|
| __lshift__(self, value, /)
| Return self<<value.
|
| __lt__(self, value, /)
| Return self<value.
|
| __mod__(self, value, /)
| Return self%value.
|
| __mul__(self, value, /)
| Return self*value.
|
| __ne__(self, value, /)
| Return self!=value.
|
| __neg__(self, /)
| -self
|
| __new__(*args, **kwargs) from builtins.type
| Create and return a new object. See help(type) for accurate signature.
|
| __or__(self, value, /)
| Return self|value.
|
| __pos__(self, /)
| +self
|
| __pow__(self, value, mod=None, /)
| Return pow(self, value, mod).
|
| __radd__(self, value, /)
| Return value+self.
|
| __rand__(self, value, /)
| Return value&self.
|
| __rdivmod__(self, value, /)
| Return divmod(value, self).
|
| __repr__(self, /)
| Return repr(self).
|
| __rfloordiv__(self, value, /)
| Return value//self.
|
| __rlshift__(self, value, /)
| Return value<<self.
|
| __rmod__(self, value, /)
| Return value%self.
|
| __rmul__(self, value, /)
| Return value*self.
|
| __ror__(self, value, /)
| Return value|self.
|
| __round__(...)
| Rounding an Integral returns itself.
| Rounding with an ndigits argument also returns an integer.
|
| __rpow__(self, value, mod=None, /)
| Return pow(value, self, mod).
|
| __rrshift__(self, value, /)
| Return value>>self.
|
| __rshift__(self, value, /)
| Return self>>value.
|
| __rsub__(self, value, /)
| Return value-self.
|
| __rtruediv__(self, value, /)
| Return value/self.
|
| __rxor__(self, value, /)
| Return value^self.
|
| __sizeof__(...)
| Returns size in memory, in bytes
|
| __str__(self, /)
| Return str(self).
|
| __sub__(self, value, /)
| Return self-value.
|
| __truediv__(self, value, /)
| Return self/value.
|
| __trunc__(...)
| Truncating an Integral returns itself.
|
| __xor__(self, value, /)
| Return self^value.
|
| bit_length(...)
| int.bit_length() -> int
|
| Number of bits necessary to represent self in binary.
| >>> bin(37)
| '0b100101'
| >>> (37).bit_length()
| 6
|
| conjugate(...)
| Returns self, the complex conjugate of any int.
|
| from_bytes(...) from builtins.type
| int.from_bytes(bytes, byteorder, *, signed=False) -> int
|
| Return the integer represented by the given array of bytes.
|
| The bytes argument must be a bytes-like object (e.g. bytes or bytearray).
|
| The byteorder argument determines the byte order used to represent the
| integer. If byteorder is 'big', the most significant byte is at the
| beginning of the byte array. If byteorder is 'little', the most
| significant byte is at the end of the byte array. To request the native
| byte order of the host system, use `sys.byteorder' as the byte order value.
|
| The signed keyword-only argument indicates whether two's complement is
| used to represent the integer.
|
| to_bytes(...)
| int.to_bytes(length, byteorder, *, signed=False) -> bytes
|
| Return an array of bytes representing an integer.
|
| The integer is represented using length bytes. An OverflowError is
| raised if the integer is not representable with the given number of
| bytes.
|
| The byteorder argument determines the byte order used to represent the
| integer. If byteorder is 'big', the most significant byte is at the
| beginning of the byte array. If byteorder is 'little', the most
| significant byte is at the end of the byte array. To request the native
| byte order of the host system, use `sys.byteorder' as the byte order value.
|
| The signed keyword-only argument determines whether two's complement is
| used to represent the integer. If signed is False and a negative integer
| is given, an OverflowError is raised.
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| denominator
| the denominator of a rational number in lowest terms
|
| imag
| the imaginary part of a complex number
|
| numerator
| the numerator of a rational number in lowest terms
|
| real
| the real part of a complex number


\*

파이썬 내부에서는 다음과 같이 표현식을 해석합니다. 먼저 round(-2.01) 값을 계산한 다음 해당 표현식의 결과에 대한 도움말(help)을 제공합니다.

(도움말(OUTPUT)을 보면 integer 에 대해 참 많은 설명이 있습니다. 나중에 파이썬에서 객체, 메소드, 속성에 관해 배우고나면 위의 방대한 도움말 출력이 더 잘 이해가 될 것입니다.)

round는 짧은 docstring을 가진 매우 간단한 함수입니다. helpprint 함수와 같이 보다 복잡하고 다양한 기능을 가진 함수를 다룰 때 더 많은 도움을 줍니다. 다음 출력 결과가 지금은 이해가지 않아도 걱정하지 마세요… 지금은 이 도움말에서 새로운 점이 있는지 확인만 하셔도 됩니다.

help(print)
Help on built-in function print in module builtins:

print(...)
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)

Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
flush: whether to forcibly flush the stream.

뭔가 발견하셨나요? 예를 들어 print가 sep라는 인자를 취할 수 있다는 것을 알 수 있습니다. 그리고 설명을 통해 인자들 사이에 넣는 문자열이라는 것을 알 수 있습니다.

함수정의(Defining functions)

내장 함수(builtin function)는 훌륭하지만, 상황에 따라 나만의 함수가 필요하기도 합니다. 아래의 간단한 예제를 살펴보겠습니다.

def least_difference(a, b, c):
diff1 = abs(a - b)
diff2 = abs(b - c)
diff3 = abs(a - c)
return min(diff1, diff2, diff3)

이 코드는 a, bc라는 세 개의 매개변수를 취하는 least_difference라는 함수를 생성합니다.

함수는 def 라는 키워드의 헤더로 시작합니다. : 다음에 들여쓰기 된 코드 블록(즉, 2번째 줄부터)은 함수가 호출 될 때 실행됩니다.

return은 함수와 관련된 또다른 고유한 키워드입니다. 파이썬에서 return 문을 만나면 함수를 즉시 종료하고 (return의)오른쪽에있는 값을 전달합니다.

least_difference()가 어떤 기능을 하는지 아시겠나요? 확실하지 않은 경우 몇 가지 예를 통해 언제든지 시도해 볼 수 있습니다.

함수에 인자를 넣어서 확인해 볼 수 있습니다

print(
least_difference(1, 10, 100),
least_difference(1, 10, 10),
least_difference(5, 6, 7), # Python allows trailing commas in argument lists. How nice is that?
)
9 0 1

혹은 help() 함수를 사용해서 설명을 읽어볼 수 있습니다

help(least_difference)
Help on function least_difference in module **main**:

least_difference(a, b, c)

아쉽게도 파이썬은 제가 작성한 코드를 읽고 설명을 작성할 만큼 똑똑하지 못한 것을 볼 수 있습니다.하지만 우리는 함수를 작성하며 이 함수에 대한 설명을 추가할 수 있습니다. 이를 docstring 이라고 합니다

Docstring

def least_difference(a, b, c):
"""Return the smallest difference between any two numbers
among a, b and c.

>>> least_difference(1, 5, -5)
4
"""
diff1 = abs(a - b)
diff2 = abs(b - c)
diff3 = abs(a - c)
return min(diff1, diff2, diff3)


docstring은 함수 바로 뒤에 삼중 따옴표 `"""`로 묶인 문자열(여러 줄로 작성 가능)입니다. 이 함수에 대한 `help()`를 호출하면 docstring이 표시됩니다.
help(least_difference)
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">Help on function least_difference in module __main__:</span><br><span class="line"></span><br><span class="line">least_difference(a, b, c)</span><br><span class="line">  Return the smallest difference between any two numbers</span><br><span class="line">  among a, b and c.</span><br><span class="line"></span><br><span class="line">  &gt;&gt;&gt; least_difference(1, 5, -5)</span><br><span class="line">  4</span><br></pre></td></tr></table></figure>

참고
docstring의 마지막 두 줄은 예제 함수의 호출과 결과입니다.
(>>>는 파이썬 대화형 셸(interactive shells)에서 사용되는 명령 프롬프트에 대한 참조입니다.) 파이썬은 예제 호출을 실행하지 않습니다.
이는 독자의 이익을 위해서입니다. 함수의 docstring에 보편적으로 하나 이상의 예제 호출을 포함하지 않지만, 설명을 읽는 사람이 함수의 기능을 이해하도록 돕는 데 매우 효과적 일 수 있습니다.
실제 예를 보려면 numpy 함수 np.eye에 대한 설명서를 참조하십시오.

훌륭한 프로그래머들은 docstring을 사용합니다. 만약 그 코드를 사용하고 버릴 계획이 아니라면 말이죠(이는 드문 경우입니다).
여러분도 docstring을 작성하는 습관을 들이시길 바랍니다.

반환값이 없는 함수들(Functions that don’t return)

만약 우리가 작성한 함수(function)에 return 키워드를 작성하지 않으면 어떻게 될까요?

def least_difference(a, b, c):
"""Return the smallest difference between any two numbers
among a, b and c.
"""
diff1 = abs(a - b)
diff2 = abs(b - c)
diff3 = abs(a - c)
min(diff1, diff2, diff3)

print(
least_difference(1, 10, 100),
least_difference(1, 10, 10),
least_difference(5, 6, 7),
)

None None None

파이썬은 그러한 함수 정의를 허용합니다. 그 함수들의 호출 한 결과는 None이라는 특별한 값을 가집니다. (이는 다른 언어의 “null”개념과 유사합니다.)

return 문이 없으면 least_difference 는 완전히 무의미해 보이지만 이 함수를 통해 아무 것도 반환하지 않고 유용한 작업을 수행 할 수 있습니다.
우리는 이러한 함수를 2개나 봤습니다: print()help()함수는 아무 것도 반환하지 않았습니다.
우리는 함수들의 부작용(side effect - 화면에 텍스트를 넣는 것)을 위해서만 호출합니다. 유용한 부작용의 다른 예는 파일에 쓰거나 입력을 수정하는 것을 포함합니다.

mystery = print()
print(mystery)
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">None</span><br><span class="line">      </span><br></pre></td></tr></table></figure>

기본 매개변수(Default arguments)

help(print) 를 호출하면 print 함수에는 몇 가지의 선택적 매개변수들(optinal arguments)이 있는 것을 볼 수 있습니다.
예를 들어, 출력하고자 하는 값들 사이에 우리가 원하는 특별한 sep 값을 지정할 수 있습니다.

print(1, 2, 3, sep=' < ')
1 < 2 < 3

만약 특정한 값을 명시하지 않으면, sep 에는 기본값인 ' '(공백) 이 들어갑니다.

print(1, 2, 3)
1 2 3

우리가 정의한 함수에 선택적 매개변수를 기본값으로 추가하는 것은 꽤 간단합니다.

def greet(who="Colin"):
print("Hello,", who)

greet()
greet(who="Kaggle")

# (In this case, we don't need to specify the name of the argument, because it's unambiguous.)

greet("world")
Hello, colin
Hello, Kaggle
Hello, world

함수들에 적용되는 함수들(Functions Applied to Functions)

처음에는 매우 추상적이라고 느낄 수 있지만 매우 매우 유용한 기술이 있습니다.
함수는 다른 함수의 매개변수로 사용될 수 있습니다. 몇 가지 예를 들어 보면 다음과 같습니다.

<div class="note primary">
        <figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">mult_by_five</span><span class="params">(x)</span>:</span></span><br><span class="line">  <span class="keyword">return</span> <span class="number">5</span> * x</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">call</span><span class="params">(fn, arg)</span>:</span></span><br><span class="line">  <span class="string">"""Call fn on arg"""</span></span><br><span class="line">  <span class="keyword">return</span> fn(arg)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">squared_call</span><span class="params">(fn, arg)</span>:</span></span><br><span class="line">  <span class="string">"""Call fn on the result of calling fn on arg"""</span></span><br><span class="line">  <span class="keyword">return</span> fn(fn(arg))</span><br><span class="line"></span><br><span class="line">print(</span><br><span class="line">  call(mult_by_five, <span class="number">1</span>),</span><br><span class="line">  squared_call(mult_by_five, <span class="number">1</span>),</span><br><span class="line">  sep=<span class="string">'\n'</span>, <span class="comment"># '\n' is the newline character - it starts a new line</span></span><br><span class="line">)</span><br><span class="line">      </span><br></pre></td></tr></table></figure>
      </div>
5
25
다른 함수에서 작동하는 함수를 "Higher order function"이라고합니다.아마 지금 당장은 잘 사용하지 않으시겠지만 파이썬에 내장된 매우 유용한 고차 함수들(higher order function)이 있습니다.

max 함수에 대한 흥미로운 예제입니다,

<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">mod_5</span><span class="params">(x)</span>:</span></span><br><span class="line">  <span class="string">"""Return the remainder of x after dividing by 5"""</span></span><br><span class="line">  <span class="keyword">return</span> x % <span class="number">5</span></span><br><span class="line"></span><br><span class="line">print(</span><br><span class="line">  <span class="string">'Which number is biggest?'</span>,</span><br><span class="line">  max(<span class="number">100</span>, <span class="number">51</span>, <span class="number">14</span>),</span><br><span class="line">  <span class="string">'Which number is the biggest modulo 5?'</span>,</span><br><span class="line">  max(<span class="number">100</span>, <span class="number">51</span>, <span class="number">14</span>, key=mod_5),</span><br><span class="line">  sep=<span class="string">'\n'</span>,</span><br><span class="line">)</span><br><span class="line">    </span><br></pre></td></tr></table></figure>
Which number is biggest?
100
Which number is the biggest modulo 5?
14
기본적으로 `max` 함수는 가장 큰 인수를 반환합니다.그러나 선택적 `key` 인자를 사용하여 함수를 전달하면 `key(x)` (일명 'argmax')를 최대화하는 인자 `x`를 반환합니다.




연습문제(Your Turn)

함수(Function)는 파이썬 프로그래밍의 새로운 세상을 열어줍니다. second Python programming exercise